package com.atguigu.gulimallcart.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.common.utils.R;
import com.atguigu.gulimallcart.Interceptor.CarInterceptor;
import com.atguigu.gulimallcart.feign.SkuFeign;
import com.atguigu.gulimallcart.service.CartService;
import com.atguigu.gulimallcart.vo.CartItemVo;
import com.atguigu.gulimallcart.vo.CartVo;
import com.atguigu.gulimallcart.vo.SkuInfoVo;
import com.atguigu.gulimallcart.vo.UserInfoTo;
import com.mysql.cj.xdevapi.JsonString;
import org.apache.catalina.User;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl  implements CartService {
    @Resource
    private ThreadPoolExecutor executor;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private SkuFeign skuFeign;
    private final String CART_PREFIX = "FIRE:cart:";
    @Override
    public CartItemVo addToCart(Long skuId, int num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String res = (String) cartOps.get(skuId.toString());
        if(StringUtils.isNotBlank(res)){
            //购物车存在  添加数量
            CartItemVo cartItemVo= JSON.parseObject(res,CartItemVo.class);
            cartItemVo.setCount(num+cartItemVo.getCount());
            cartOps.put(skuId.toString(),JSON.toJSONString(cartItemVo));
            return cartItemVo;
        }else{
            //购物车不存在  添加购物车信息
            CartItemVo cartItemVo=new CartItemVo();
            CompletableFuture<Void> thread1 = CompletableFuture.runAsync(() -> {
                R<SkuInfoVo> info = skuFeign.info(skuId);
                SkuInfoVo skuInfo = JSONObject.parseObject(JSONObject.toJSONString(info.get("pmsSkuInfo")), SkuInfoVo.class);
                cartItemVo.setSkuId(skuInfo.getSkuId());
                cartItemVo.setImage(skuInfo.getSkuDefaultImg());
                cartItemVo.setTitle(skuInfo.getSkuTitle());
                cartItemVo.setCheck(true);
                cartItemVo.setCount(num);
                cartItemVo.setPrice(skuInfo.getPrice());
            }, executor);

            CompletableFuture<Void> thread2 = CompletableFuture.runAsync(() -> {
                //获取销售属性  TODO:  测试
                List<String> saleAttrValues = skuFeign.getSaleAttrValueBySku(skuId);
                cartItemVo.setAttr(saleAttrValues);
            }, executor);

            CompletableFuture.allOf(thread1,thread2).get();
            cartOps.put(skuId.toString(),JSONObject.toJSONString(cartItemVo));
            return cartItemVo;
        }
    }

    @Override
    public CartItemVo getCarSkuInfo(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = this.getCartOps();
        String carInfo = cartOps.get(skuId.toString()).toString();
        CartItemVo cartItemVo = JSON.parseObject(carInfo, CartItemVo.class);
        return cartItemVo;
    }

    @Override
    public CartVo myCart() throws ExecutionException, InterruptedException {
        UserInfoTo userInfoTo = CarInterceptor.threadLocal.get();
        CartVo cartVo=new CartVo();
        String cartKey=CART_PREFIX+userInfoTo.getUserKey();
        List<CartItemVo> cartItems = getCart(cartKey);
        if(userInfoTo.getUserId()==null){
            //未登录
            cartVo.setCartItemVoList(cartItems);
        }else{
            //登录   合并购物车
            if(!CollectionUtils.isEmpty(cartItems)){
                for (CartItemVo cartItem:cartItems) {
                    addToCart(cartItem.getSkuId(),cartItem.getCount());
                }
            }
            List<CartItemVo> cartItems1 = getCart(CART_PREFIX+userInfoTo.getUserId());
            cartVo.setCartItemVoList(cartItems1);
            clearCart(cartKey);
        }
        return cartVo;
    }

    @Override
    public void clearCart(String cartKey) {
        stringRedisTemplate.delete(cartKey);
    }

    @Override
    public void deleteCart(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = this.getCartOps();
        cartOps.delete(skuId.toString());
    }

    @Override
    public List<CartItemVo> getUserCartItems() {
        UserInfoTo userInfoTo = CarInterceptor.threadLocal.get();
        List<CartItemVo> cartItemVoList= getCart(CART_PREFIX+userInfoTo.getUserId());
        List<CartItemVo> collect = cartItemVoList.stream().filter(e -> e.getCheck()).collect(Collectors.toList());
        return collect;
    }

    public  BoundHashOperations<String, Object, Object> getCartOps(){
        //判断是否登录
        UserInfoTo userInfoTo = CarInterceptor.threadLocal.get();
        String key="";
        if(userInfoTo.getUserId()!=null){
            //用户已登录    用户购物车
            key=CART_PREFIX+userInfoTo.getUserId();
        }else{
            //未登录    临时购物车
            key=CART_PREFIX+userInfoTo.getUserKey();
        }
         return stringRedisTemplate.boundHashOps(key);
    }

    //获取购物车数据
    public List<CartItemVo> getCart(String cartKey){
        List<Object> values = stringRedisTemplate.opsForHash().values(cartKey);
        Optional<List<CartItemVo>> cartItemVos = Optional.ofNullable(values).map(v -> {
            List<CartItemVo> cartItems = v.stream().map(s -> {
                CartItemVo cartItemVo = JSON.parseObject(s.toString(), CartItemVo.class);
                return cartItemVo;
            }).collect(Collectors.toList());
            return cartItems;
        });
        List<CartItemVo> cartItems = cartItemVos.get();
        return cartItems;
    }


}
